----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    14:44:53 02/24/2012 
-- Design Name: 
-- Module Name:    captador - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity captador is
    Port ( --PC ENTRADA
			  PC_IN : in  STD_LOGIC_VECTOR (9 downto 0);
			  
			  --ENTRADAS DEL MUX COMO POSIBLES SALIDAS
			  PILA_OUT : in  STD_LOGIC_VECTOR (9 downto 0);
			  OFFSET : in  STD_LOGIC_VECTOR (7 downto 0);
           JUMP_ADDRESS : in  STD_LOGIC_VECTOR (9 downto 0);
           INT_RET : in  STD_LOGIC_VECTOR (9 downto 0);
			  
			  --CONDICIONANTES, SENYALES DE CONTROL UNIT
           IS_BRANCH : in  STD_LOGIC;
			  BRANCHOP : in STD_LOGIC_VECTOR (1 downto 0);
           IS_RETI : in  STD_LOGIC;
           IS_SUB_RET : in  STD_LOGIC;
           IS_JUMP : in  STD_LOGIC;
           IS_INTR : in  STD_LOGIC;
			  IS_CALL : in STD_LOGIC;
			  
			  --SALIDAS, CONTROL DE PILA, NUEVO PC Y SALIDA A PILA
           PC_NEW : out  STD_LOGIC_VECTOR (9 downto 0);
			  stackOut : out STD_LOGIC_VECTOR (9 downto 0);
			  stack_op : out STD_LOGIC;
			  enableStack : out STD_LOGIC);
			  
end captador;


architecture Behavioral of captador is
begin

process (PILA_OUT, OFFSET, JUMP_ADDRESS, PC_IN, INT_RET, IS_BRANCH, IS_RETI, IS_SUB_RET, IS_JUMP, IS_INTR, IS_CALL)

--Nuevo PC calculado a variable para asignar a senyal salida al final
variable nuevoPC : STD_LOGIC_VECTOR (9 downto 0);
--Operacion de pila a variable para asignar a senyal salida al final
variable opStack : STD_LOGIC := '0';
--Control de pila para asignar a senyal salida al final
variable enStack : STD_LOGIC := '0';
begin
	-- ACCIONES A TOMAR POR LAS SENYALES DE CONTROL
	if (IS_RETI = '1') then -- RETORNO DE INTERRUPCION
		nuevoPC := INT_RET;
		enStack := '0';
		opStack := '0';
	elsif (IS_SUB_RET = '1') then -- RETORNO DE SUBRUTINA
		nuevoPC := PILA_OUT;
		enStack := '1';
		opStack := '0';
	elsif (IS_BRANCH = '1') then -- SI ES BRANCH
		enStack := '0';
		if (BRANCHOP = "00" OR BRANCHOP = "10") then
			nuevoPC := PC_IN + ext (OFFSET, 10);
		elsif (BRANCHOP = "01" OR BRANCHOP = "11") then
			nuevoPC := PC_IN - ext (OFFSET, 10);
		end if;
	elsif (IS_CALL = '1' ) then --LLAMADA A SUBRUTINA SE ACTIVA PILA EN MODO APILAR, SUMAMOS UNO A PC Y 
		opStack := '1';
		enStack := '1';
		nuevoPC := JUMP_ADDRESS;
		stackOut <= PC_IN + ext("1", 10);		
	elsif (IS_JUMP = '1') then -- SALTO INCONDICIONAL
		nuevoPC := JUMP_ADDRESS;
	elsif (IS_INTR = '1') then -- LLEGA INTERRUPCION
		nuevoPC := (others => '0');
		enStack := '0';
	else
		nuevoPC := PC_IN + ext("1", 10);
		enStack := '0';
	end if;	
	
	PC_NEW <= nuevoPC;
	stack_Op <= opStack;
	enableStack <= enStack;
	if (IS_CALL = '0') then
		stackOut <= (others => '0');
	end if;
	
end process;

end Behavioral;
